package serializable;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author yangwenqi
 * @decs TODO
 * @date 2025/5/14
 * 防止序列化数据被篡改
 * 1.序列化时给对象生成一个hash值
 * 2.反序列化是，再为对象生成一个hash值，两者作对比
 * 3.若发生改变则抛出异常阻止篡改
 *
 */
public class Person implements Serializable {
    private static final long serialVersionUID = -8762093111359704528L;
    //如果是Static则把序列化和反序列化放在同一个类中时，则序列化不会成功，但transient会成功
    private transient String name;
    private int age;
    private String address;
    private String  hash;
    public void setHash(){
        this.hash=getHash();
    }
    //生成hash算法 MD5加密
    private String getHash() {
        try{
            String str=name+age+address;
            //通过MD5方式
            MessageDigest messageDigest=MessageDigest.getInstance("MD5");
            //更新上处理的字符串
            messageDigest.update(str.getBytes());
            //转换成字符数组
            byte[] bytes=messageDigest.digest();
            //转换成16进制
            StringBuffer hexString=new StringBuffer();
            for(byte b:bytes){
                hexString.append(String.format("%02X",b));
            }
            return hexString.toString();

        }catch(NoSuchAlgorithmException e){
            e.printStackTrace();
        }
        return "error hash";
    }

    //防止数据被篡改
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        //默认读取数据
        in.defaultReadObject();
        if(this.hash.equals("error hash")){
            //防止被篡改抛出异常
            throw new IllegalArgumentException("对象信息被篡改！");
        }
        System.out.println(this);
    }
    public Person() {
    }

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return address
     */
    public String getAddress() {
        return address;
    }

    /**
     * 设置
     * @param address
     */
    public void setAddress(String address) {
        this.address = address;
    }

    public String toString() {
        return "Person{name = " + name + ", age = " + age + ", address = " + address + "}";
    }
}
